#include "Head.h"
#include "ADTStructure.h"

namespace Creator 
{
	class _declspec(dllexport) ADTCreator
	{
	private:
		MVER ver;
		MHDR hdr;
		MH2O h2o;
		std::vector<MH2O::MH2O_H> h2o_h;
		std::vector<MH2O::MH2O_I> h2o_i;
		//std::vector<MH2O::MH2O_D> h2o_d;
		std::vector<MH2O::MH2O_R> h2o_r;
		std::vector<MCNK> cnk;
		std::vector<MCVT> cvt;
		std::vector<MCSE> cse;
		MFBO fbo;
	public:
		ADTCreator()
		{
			h2o_h.resize(256);
			h2o_i.resize(256);
			h2o_r.resize(256);
			cnk.resize(256);
			cvt.resize(256);
			cse.resize(256);
		}

		~ADTCreator(){ }

		MVER FillMVER()
		{
			ver.signature = 'MVER';
			ver.size = 0x4;
			ver.version = 0x12;
			return ver;
		}
		MVER FillMVER(uint32 version)
		{
			ver.signature = 'MVER';
			ver.size = 0x4;
			ver.version = version;
			return ver;
		}

		MHDR FillMHDR()
		{
			hdr.signature = 'MHDR';
			hdr.size = sizeof(uint32) * 0x10;
			hdr.flag = 0x1;
			for(uint32 i = 0; i < 0xF; ++i)
			{
				if(i == 9)
				{
					hdr.Offsets.push_back(hdr.size 
										  + (sizeof(uint32) * 2 
										  + (sizeof(MH2O::MH2O_H) * 256) 
										  + (sizeof(MH2O::MH2O_I) * 256)
										  + ((sizeof(char) * 64) * 256))
										  + (((sizeof(uint32) * 31) + (sizeof(float) * 3)) * 256)
										  + ((sizeof(float) * 145 + sizeof(uint32) * 2) * 256)
										  + (sizeof(MCSE) * 256));
				}
				else if(i == 0xA) 
				{
					hdr.Offsets.push_back(hdr.size);
				}
				hdr.Offsets.push_back(0x0);
			}
			return hdr;
		}

		MH2O FillMH2O()
		{
			h2o.signature = 'MH2O';
			h2o.size = sizeof(uint32) * 2
				       + sizeof(MH2O::MH2O_H) * 256
					   + sizeof(MH2O::MH2O_I) * 256
					   + (sizeof(char) * 64) * 256;
			return h2o;
		}
		MH2O::MH2O_H FillMH2O_H()
		{
			for(int i = 0; i < 256; ++i)
			{
				//Header
				h2o_h[i].ofsInfo = sizeof(MH2O::MH2O_H) * i-256;
				h2o_h[i].nLayer = 1;
				h2o_h[i].ofsRender = (sizeof(MH2O::MH2O_H) * i-256) + (sizeof(MH2O::MH2O_I) * 256);
				return h2o_h[i];
			}
		}
		MH2O::MH2O_I FillMH2O_I()
		{
			for(int i = 0; i < 256; ++i)
			{
				//Information
				h2o_i[i].LiquidType = 0x1;
				h2o_i[i].flags = 0;
				h2o_i[i].heightLevel1 = 1.0f;
				h2o_i[i].heightLevel2 = 2.0f;
				h2o_i[i].xOffset = 0;
				h2o_i[i].yOffset = 0;
				h2o_i[i].width = 9;
				h2o_i[i].height = 9;
				h2o_i[i].Mask2 = 0x0; // No need, but i'm not sure yet.
				h2o_i[i].ofsHeightmapData = 0x0;
				return h2o_i[i];				
			}
		}
		MH2O::MH2O_R FillMH2O_R()
		{
			for(int i = 0; i < 256; ++i)
			{
				for(int j = 0; j < 8; ++j)
				{
					h2o_r[i].Render[j] = 0xFF; //Bit: 1111111111111111 creates a beatyfull liquid chunk
				}
				return h2o_r[i];
			}
		}

		MCNK FillMCNK()
		{
			for(int i = 0; i < 256; ++i)
			{
				cnk[i].signature = 'MCNK';
				cnk[i].size = ((sizeof(uint32) * 31) + (sizeof(float) * 3)) * 256;
				cnk[i].flags = 0x0; //don't want to use an unwanted chunk
				cnk[i].IndexX = i % 16; //don't know yet
				cnk[i].IndexY = i / 16;
				cnk[i].nLayers = 0x0;
				cnk[i].nDoodadRefs = 0x0;
				cnk[i].ofsHeight = cnk[i].size;
				cnk[i].ofsNormal = 0x0;
				cnk[i].ofsLayer = 0x0;
				cnk[i].ofsRefs = 0x0;
				cnk[i].ofsAlpha = 0x0;
				cnk[i].sizeAlpha = 0x0;
				cnk[i].ofsShadow = 0x0;
				cnk[i].sizeShadow = 0x0;
				cnk[i].areaid = 0x1;
				cnk[i].nMapObjRefs = 0x0;
				cnk[i].holes = 0x0;
				cnk[i].unused1 = 0x0;
				cnk[i].unused2 = 0x0;
				cnk[i].unused3 = 0x0;
				cnk[i].unused4 = 0x0;
				cnk[i].predTex = 0x0;
				cnk[i].noEffectDoodad = 0x0;
				cnk[i].ofsSndEmitters = cnk[i].size + (sizeof(float) * 145 + 0x8);
				cnk[i].nSndEmitters = 0x0;
				cnk[i].ofsLiquid = 0x0;
				cnk[i].sizeLiquid = 0x0;
				cnk[i].position.x = cnk[i].IndexX + ((533.0f + 1.0f / 3.0f)/16.0f);
				cnk[i].position.y = 0.0f;
				cnk[i].position.z = cnk[i].IndexY + ((533.0f + 1.0f / 3.0f)/16.0f);
				cnk[i].ofsMCCV = 0x0;
				cnk[i].ofsMCLV = 0x0;
				cnk[i].unused = 0x0;

				return cnk[i];
			}
		}

		MCVT FillMCVT()
		{
			for(int j  = 0; j < 256; ++j)
			{
				cvt[j].signature = 'MCVT';
				cvt[j].size= sizeof(float) * 145;
				cvt[j].height.resize(145);
				for(int i = 0; i < 145; ++i)
				{
					cvt[j].height.push_back(0.0f);
				}
				return cvt[j];
			}
		}

		MCSE FillMCSE()
		{
			for(int i = 0; i < 256; ++i)
			{
				cse[i].signature = 'MCSE';
				cse[i].size = 0x0;

				return cse[i];
			}
		}

		MFBO FillMFBO()
		{
			fbo.signature = 'MFBO';
			fbo.size = sizeof(short) * 18;
			for(int i = 0; i < 9; ++i)
			{
				fbo.maximum[i] = 0x01f4;//just some standard values in here
				fbo.minimum[i] = 0xffa6;
			}
			return fbo;
		}
	};
};